/*
 * @(#)DynaClassLoader.java
 *
 * Copyright (c) 2006 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.core;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;

/**
 * <p>
 * Class Name: DynaClassLoader.java
 * </p>
 * <p>
 * Description: This class is the class loader to load class dynamically.
 * </p>
 * 
 * @author greatwall shao
 * @company DCIVision Limited
 * @creation date 2006-08-23
 */
public class DynaClassLoader extends ClassLoader {

  private static final Log log = LogFactory.getLog(DynaClassLoader.class);

  private String path = SystemParameterFactory.getSystemParameter(SystemParameterConstant.WORKFLOW_AUTOMATIC_TASK_BINDIR);

  private String fileType = ".class";

  private ClassLoader currentClassLoader = null;

  public DynaClassLoader() {
    this(Thread.currentThread().getContextClassLoader());

  }

  public DynaClassLoader(ClassLoader classLoader) {
    super(classLoader);
    currentClassLoader = classLoader;
  }

  public String getPath() {
    return path;
  }

  public void setPath(String path) {
    this.path = path;
  }

  public Class findClass(String name) {
    Class clazz = null;
    try {
      clazz = currentClassLoader.loadClass(name);
    } catch (ClassNotFoundException e) {
      log.error(e, e);
      clazz = null;
    }
    if (clazz == null) {
      byte[] data = loadClassData(name);
      clazz = defineClass(null, data, 0, data.length);
    }
    return clazz;
  }

  public byte[] loadClassData(String name) {
    InputStream inputStream = null;
    ByteArrayOutputStream baos = null;
    byte[] data = null;
    try {
      inputStream = new FileInputStream(new File(path, name.replace('.', '/') + fileType));

      baos = new ByteArrayOutputStream();
      int ch = 0;
      while ((ch = inputStream.read()) != -1) {
        baos.write(ch);
      }
      data = baos.toByteArray();
    } catch (IOException e) {
      log.error(e, e);
    } finally {
      try {
        inputStream.close();
        baos.close();
      } catch (IOException e) {
        log.error(e, e);
      }
    }

    return data;
  }

}
